<template>
  <main>
    <a-row>
      <a-col :span="12">
        <a-flex>
          <a-avatar :src="avatorSrc" @click="showAvator()" />
          <a-flex vertical>
            <a-button style="margin-left: 5px" @click="onLogin"> Login </a-button>
            <a-upload
              :file-list="fileList"
              list-type="picture"
              :before-upload="beforeUpload"
              @remove="handleRemove"
              :max-count="1"
            >
              <a-button>
                <upload-outlined></upload-outlined>
                Upload
              </a-button>
            </a-upload>
            <a-button
              type="primary"
              :disabled="fileList!.length === 0"
              :loading="uploading"
              style="margin-top: 16px"
              @click="handleUpload"
            >
              {{ uploading ? 'Uploading' : 'Start Upload' }}
            </a-button>
          </a-flex>
          <a-row style="margin-left: 80px">
            <a-col flex="100px" style="padding-right: 5px">
              <a-row>
                <a-col :span="24"
                  ><a-input v-model:value="username" placeholder="input username"
                /></a-col>

                <a-col :span="24" style="padding-top: 12px">
                  <a-input-password v-model:value="password" placeholder="input password"
                /></a-col>
              </a-row>
            </a-col>
            <a-col flex="auto">
              <a-textarea style="color: black" :rows="3" :value="loginResponse"> </a-textarea>
            </a-col>
          </a-row>
        </a-flex>
      </a-col>
      <a-col :span="12">
        <a-button style="margin-left: 5px" @click="onRegist"> Regist </a-button>
        <a-row style="margin-left: 80px">
          <a-col flex="100px" style="padding-right: 5px">
            <a-row>
              <a-col :span="24"
                ><a-input v-model:value="username2" placeholder="input username"
              /></a-col>

              <a-col :span="24" style="padding-top: 12px">
                <a-input-password v-model:value="password2" placeholder="input password"
              /></a-col>
            </a-row>
          </a-col>
          <a-col flex="auto">
            <a-textarea style="color: black" :rows="3" :value="addResponse"> </a-textarea>
          </a-col>
        </a-row>
      </a-col>
    </a-row>

    <a-button style="margin-left: 5px" @click="onUserProfile"> Profile </a-button>
    <div style="margin-left: 80px">
      <a-textarea style="color: black" :rows="3" :value="tokenResponse"> </a-textarea>
    </div>

    <a-row style="margin-top: 30px; margin-bottom: 5px">
      <a-button style="margin-left: 5px" @click="productAdd"> Add Product </a-button>
      <a-button style="margin-left: 5px" @click="orderAdd"> Add Order </a-button>
      <a-button style="margin-left: 5px" @click="orderGet"> Get Order </a-button>
    </a-row>
    <div style="margin-left: 80px">
      <a-textarea style="color: black" :rows="3" :value="testResponse"> </a-textarea>
    </div>

    <a-row style="margin-top: 5px; margin-bottom: 5px">
      <a-button style="margin-left: 5px" @click="productGet"> All Products </a-button>
      <a-button style="margin-left: 5px" @click="productPage"> Paginate Product </a-button>
      <a-pagination
        v-model:current="currentPage"
        v-model:page-size="pageSizeRef"
        :page-size-options="pageSizeOptions"
        show-quick-jumper
        :total="totalDatas"
        @change="onChangePage"
        @showSizeChange="onShowSizeChange"
      >
        <template #buildOptionText="props">
          <span v-if="props.value !== '100'">{{ props.value }}条/页</span>
          <span v-else>全部</span>
        </template>
      </a-pagination>
    </a-row>

    <a-row style="margin-top: 30px; margin-bottom: 5px">
      <a-button style="margin-left: 5px" @click="downloadFile('pdf')"> Download Pdf </a-button>
      <a-button style="margin-left: 5px" @click="downloadFile('single')">
        Download Single
      </a-button>
      <a-button style="margin-left: 5px" @click="downloadFile('zip')"> Download Zip </a-button>
      <a-button style="margin-left: 5px" @click="downloadFile('csv')"> Download CSV </a-button>
      <a-button style="margin-left: 5px" @click="generalExcel()"> General Excel </a-button>
    </a-row>

    <div style="margin-top: 30px">
      <a-row style="margin-top: 5px; margin-bottom: 5px">
        <a-space>
          <a-button style="margin-left: 5px" @click="sseAdd"> Add SSE </a-button>
          <a-select
            v-model:value="sseNewValue"
            :options="sseoptions"
            label-in-value
            :maxTagCount="2"
            mode="tags"
            :token-separators="[',']"
            size="middle"
            placeholder="Automatic tokenization"
            style="width: 400px"
          ></a-select>
          <a-button style="margin-left: 5px" @click="setUserSSE"> Set User SSE </a-button>
          <a-select
            v-model:value="sseUserValue"
            :options="sseoptions"
            label-in-value
            :maxTagCount="2"
            mode="multiple"
            size="middle"
            placeholder="Please select"
            style="width: 400px"
          ></a-select>
        </a-space>
      </a-row>
      <a-row>
        <a-col :span="12" style="display: inline-flex">
          <a-button style="margin-left: 5px" @click="testSSE1" :disabled="sseUserValue.length < 1">
            test SSE - {{ sseUserValue.length > 0 ? sseUserValue[0].label : '' }}
          </a-button>
          <a-textarea style="color: black; margin-top: 30px" :rows="3" :value="sseResponse1">
          </a-textarea>
        </a-col>

        <a-col :span="12" style="display: inline-flex">
          <a-button style="margin-left: 5px" @click="testSSE2" :disabled="sseUserValue.length < 2">
            testSSE - {{ sseUserValue.length > 1 ? sseUserValue[1].label : '' }}
          </a-button>
          <a-textarea style="color: black; margin-top: 30px" :rows="3" :value="sseResponse2">
          </a-textarea>
        </a-col>
      </a-row>
    </div>
  </main>
</template>

<script setup lang="ts">
import { watch, ref, type Ref } from 'vue'
import { EventSourcePolyfill } from 'event-source-polyfill'
import {
  userLogin,
  userProfile,
  userRegist,
  getProduct,
  getPaginateProducts,
  getOrder,
  addOrder,
  addProduct,
  addSse,
  addUserSse,
  getSseList,
  getFile,
  createExcel,
  sseSend
} from '../api/UserAPI' //引入api
import { download, DownloadType, UploadEventType, uploadSingle } from '../api/CommonAPI' //引入api

import { onMounted } from 'vue'
import type { SelectProps } from 'ant-design-vue'
import type { UploadProps } from 'ant-design-vue'
import { UploadOutlined } from '@ant-design/icons-vue'

const token = window.localStorage.getItem('token')
const avatorSrc = ref<string>('')
// window.localStorage.clear()
const loginResponse = ref<string>('')
const sseResponse1 = ref<string>('')
const sseResponse2 = ref<string>('')
const tokenResponse = ref<string>('')
const addResponse = ref<string>('')
const testResponse = ref<string>('')
const username = ref<string>('000000')
const password = ref<string>('111111')
const username2 = ref<string>('000000')
const password2 = ref<string>('111111')
if (navigator.userAgent.indexOf('Chrome') > 0) {
  username.value = '000000'
  password.value = '111111'
} else {
  username.value = '111111'
  password.value = '111111'
}

onMounted(() => {
  getAllSse()
})

async function onLogin() {
  let rlt = await userLogin(username.value, password.value)
  if (rlt.data) {
    loginResponse.value = JSON.stringify(rlt.data)
  } else {
    loginResponse.value = JSON.stringify(rlt)
  }
  console.log('onLogin', avatorSrc.value, JSON.stringify(rlt))
}
async function showAvator() {
  avatorSrc.value = await getFile(DownloadType.Avator)
  console.log('showAvator', avatorSrc.value)
}
async function onRegist() {
  let rlt = await userRegist(username2.value, password2.value)
  console.log('onAdd', JSON.stringify(rlt))
  if (rlt.data) {
    addResponse.value = JSON.stringify(rlt.data)
  } else {
    addResponse.value = JSON.stringify(rlt)
  }
}

async function onUserProfile() {
  let rlt = await userProfile()
  if (rlt.data) {
    rlt.data.profile.sses.forEach((sse) => {
      sseUserValue.value?.push({ label: sse.name, value: sse.sseId })
    })
    tokenResponse.value = JSON.stringify(rlt.data)
  } else {
    tokenResponse.value = JSON.stringify(rlt)
  }
}
//******************************************* */
const sseNewValue = ref<{ value: number | string; label: string }[]>([])
watch(sseNewValue, () => {
  console.log('sseNewValue', sseNewValue.value)
})

const sseoptions = ref<SelectProps['options']>([])

async function getAllSse() {
  let rlt = await getSseList()
  if (rlt.data) {
    let arr = rlt.data as Record<string, any>[]
    arr.forEach((item) => {
      sseoptions.value?.push({ label: item.name, value: item.sseId })
    })
  }
}

async function sseAdd() {
  const dtos: { name: string; comment?: string }[] = []

  sseNewValue.value.forEach((item) => {
    let name = 'Name_' + item.value
    if (sseoptions.value) {
      for (let i = 0; i < sseoptions.value?.length; i++) {
        if (sseoptions.value[i].value == item.value) {
          name = sseoptions.value[i].label
        }
      }
    }
    dtos.push({ name: name, comment: 'C_' + name })
  })

  let rlt = await addSse(dtos)
  if (rlt.data) {
    let arr = rlt.data as Record<string, any>[]
    sseoptions.value?.splice(0, sseoptions.value.length)
    sseNewValue.value?.splice(0, sseNewValue.value.length)
    arr.forEach((item) => {
      sseoptions.value?.push({ label: item.name, value: item.sseId })
      sseNewValue.value?.push(item.sseId)
    })
    testResponse.value = JSON.stringify(rlt.data)
  } else {
    testResponse.value = JSON.stringify(rlt)
  }
}

const sseUserValue = ref<{ value: number | string; label: string }[]>([])
async function setUserSSE() {
  const dtos: (string | number)[] = []

  sseUserValue.value.forEach((item) => {
    dtos.push(item.value)
  })
  let rlt = await addUserSse(dtos)
  if (rlt.data) {
    testResponse.value = JSON.stringify(rlt.data)
  } else {
    testResponse.value = JSON.stringify(rlt)
  }
}

//******************************************* */
async function productGet() {
  console.log('productGet11111', '----------')
  let rlt = await getProduct()
  console.log('productGet', rlt)
  if (rlt.data) {
    testResponse.value = JSON.stringify(rlt.data)
  } else {
    testResponse.value = JSON.stringify(rlt)
  }
}
async function productPage() {
  let rlt = await getPaginateProducts(currentPage.value, pageSizeRef.value)
  if (rlt.data) {
    console.log('getPaginateProducts', rlt.data.totalCount)
    totalDatas.value = rlt.data.totalCount
    testResponse.value = JSON.stringify(rlt.data)
  } else {
    testResponse.value = JSON.stringify(rlt)
  }
}

async function orderGet() {
  let rlt = await getOrder(1)
  if (rlt.data) {
    testResponse.value = JSON.stringify(rlt.data)
  } else {
    testResponse.value = JSON.stringify(rlt)
  }
}

async function productAdd() {
  let rlt = await addProduct({ name: '999Name', price: 999 })
  if (rlt.data) {
    testResponse.value = JSON.stringify(rlt.data)
  } else {
    testResponse.value = JSON.stringify(rlt)
  }
}
async function orderAdd() {
  let rlt = await addOrder()
  if (rlt.data) {
    testResponse.value = JSON.stringify(rlt.data)
  } else {
    testResponse.value = JSON.stringify(rlt)
  }
}

console.log('----', navigator.userAgent)
let eventSSE1: EventSource | null = null
let eventSSE2: EventSource | null = null
function testSSE1() {
  // readyState: 0->Connecting, 1->Open，2->Closed
  if (eventSSE1) {
    if (eventSSE1.readyState == 0) {
      return
    } else if (eventSSE1.readyState == 1) {
      eventSSE1.close()
      eventSSE1 = null
      return
    }
  }
  eventSSE1 = testSSE12(1, sseResponse1)
}
function testSSE2() {
  // readyState: 0->Connecting, 1->Open，2->Closed
  if (eventSSE2) {
    if (eventSSE2.readyState == 0) {
      return
    } else if (eventSSE2.readyState == 1) {
      eventSSE2.close()
      eventSSE2 = null
      return
    }
  }
  eventSSE2 = testSSE12(2, sseResponse2)
}
function testSSE12(sseType: number, sseResponse: Ref<string>) {
  let arr = sseUserValue.value
  const token = window.localStorage.getItem('token')
  const url = 'http://127.0.0.1:3000/fhc/sse/listen/' + sseType
  console.log('EventSource:', url, token)
  const eventSSE: EventSource | null = new EventSourcePolyfill(url, {
    withCredentials: false,
    heartbeatTimeout: 60000,
    headers: {
      token: token!
    }
  })
  eventSSE!.addEventListener('open', (e) => {
    console.log('testSSE open:', e)
    sseResponse.value = 'open'
  })
  eventSSE!.addEventListener('message', (e: MessageEvent<any>) => {
    sseResponse.value = JSON.stringify(e.data) + '\n' + sseResponse.value
  })
  eventSSE!.addEventListener('error', (e) => {
    let errorMsg = ''
    if (e.error && e.error.message) {
      errorMsg = e.error.message
    } else if (e.statusText) {
      errorMsg = e.statusText
    }
    console.log('testSSE error:', errorMsg, e)
    sseResponse.value = errorMsg + '\n' + sseResponse.value
  })
  eventSSE!.addEventListener('close', (e) => {
    sseResponse.value = 'close\n' + sseResponse.value
  })
  return eventSSE
}

//*****************************  PAGE  *****************************/

const pageSizeRef = ref(10)
const pageSizeOptions = ref<string[]>(['10', '20', '30', '50', '100'])
const currentPage = ref<number>(1)
const totalDatas = ref<number>(500)
const onChangePage = (pageNumber: number) => {
  console.log('Page: ', pageNumber)
}

watch(
  () => currentPage.value,
  () => {
    console.log('watch currentPage: ', currentPage.value)
    productPage()
  }
)

const onShowSizeChange = (current: number, pageSize: number) => {
  //会导致触发onChangePage，但是currentPage并未变化，所以：
  //1.不建议onChangePage，使用watch去翻页
  //2.这里根据当前翻页参数重新刷新数据
  console.log(current, pageSize)
  productPage()
}

//*****************************  downloadFile  *****************************/

const downloadFile = async (fileType: DownloadType) => {
  let rlt = await download(null, fileType)
  if (rlt.data) {
    testResponse.value = JSON.stringify(rlt.data)
  } else {
    testResponse.value = JSON.stringify(rlt)
  }
}

const generalExcel = async (fileType: DownloadType) => {
  await createExcel()
}

//*****************************  UPLOAD  *****************************/

const uploading = ref<boolean>(false)
const fileList = ref<UploadProps['fileList']>([])
const beforeUpload: UploadProps['beforeUpload'] = (file) => {
  fileList.value = [...(fileList.value || []), file]
  return false
}

const handleRemove: UploadProps['onRemove'] = (file) => {
  const index = fileList.value!.indexOf(file)
  const newFileList = fileList.value!.slice()
  newFileList.splice(index, 1)
  fileList.value = newFileList
}

const handleUpload = async () => {
  uploading.value = true

  let rlt = await uploadSingle(fileList.value![0], {
    uploadKey: 'uk11',
    uploadType: UploadEventType.Avator_Add
  })
  if (rlt.data) {
    testResponse.value = JSON.stringify(rlt.data)
  } else {
    testResponse.value = JSON.stringify(rlt)
  }
  uploading.value = false
}
</script>
